package service

import (
	"fmt"
	"reflect"
	"remoteGo/remote/io"
	"strconv"
)

type Slave struct {
	server io.ServerSocket
}

func NewTCPSlave(port int) *Slave {
	return &Slave{
		server: io.NewTCPServerSocket("0.0.0.0:" + strconv.Itoa(port)),
	}
}

func (s *Slave) StartListen() {
	go func() {
		for {
			conn, err := s.server.Accept()
			if err != nil {
				fmt.Println(err)
				continue
			}
			s.Handle(conn)
		}
	}()
}

func (s *Slave) Handle(conn io.Socket) {
	go func() {
		for {
			var x Invoke
			fmt.Println("wait for")
			err := conn.Recv(&x)
			if err != nil {
				fmt.Println(err)
				break
			}
			fmt.Println("invoke", x.Uid)
			f := GetFunc(x.Uid)
			values := make([]reflect.Value, len(x.Args))
			for i, arg := range x.Args {
				cpVal, ok := arg.(ChanProxy)
				if ok {
					c := make(chan any)
					cproxy := &ChanSendProxy{
						cp:       cpVal,
						socket:   conn,
						chanVal:  reflect.ValueOf(c),
						stopChan: nil,
					}
					cproxy.Redirect()
					values[i] = reflect.ValueOf(c)
				} else {
					values[i] = reflect.ValueOf(arg)
				}
			}
			reflect.ValueOf(f).Call(values)
			//TODO: stop chan Proxy
		}
	}()
}
